from abc import ABC, abstractmethod
from typing import Optional

from pydantic import Field

from src.agent.base import BaseAgent
from src.llm import LLM
from src.schema import AgentState, Memory


class ReActAgent(BaseAgent, ABC):
    """ReAct (Reasoning + Acting) 模式智能代理基类。
    
    实现了经典的 ReAct 框架，通过"思考-行动"循环来解决问题：
    1. Think（思考）：分析当前状态，决定是否需要行动
    2. Act（行动）：执行具体的操作或决策
    
    主要特点：
    - 分离思考和执行逻辑，提高代码清晰度
    - 支持条件性执行，不是每次思考都必须行动
    - 灵活的步骤控制，可以根据思考结果决定后续流程
    
    适用场景：
    - 需要复杂推理的任务
    - 多步骤决策过程
    - 条件性执行的工作流
    """

    # 代理基本信息
    name: str = Field(..., description="代理名称，用于标识和日志记录")
    description: Optional[str] = Field(None, description="代理功能描述，可选")

    # 提示词配置
    system_prompt: Optional[str] = Field(
        None, description="系统提示词，定义代理的角色和基本行为"
    )
    next_step_prompt: Optional[str] = Field(
        None, description="下一步提示词，指导每个执行步骤的决策"
    )

    # 核心组件
    llm: Optional[LLM] = Field(
        default_factory=LLM, description="大语言模型实例，用于推理和决策"
    )
    memory: Memory = Field(
        default_factory=Memory, description="记忆组件，存储对话历史和上下文"
    )
    state: AgentState = Field(
        default=AgentState.IDLE, description="代理当前状态"
    )

    # 执行控制参数
    max_steps: int = Field(default=10, description="最大执行步数，防止无限循环")
    current_step: int = Field(default=0, description="当前执行步数计数器")

    @abstractmethod
    async def think(self) -> bool:
        """思考阶段：分析当前状态并决定下一步行动。
        
        这是 ReAct 框架的第一个阶段，负责：
        1. 分析当前情况和可用信息
        2. 评估目标完成情况
        3. 决定是否需要进一步行动
        4. 规划下一步的具体操作
        
        Returns:
            bool: True 表示需要执行行动，False 表示思考完成无需行动
            
        Note:
            子类必须实现此方法，定义具体的思考逻辑
        """

    @abstractmethod
    async def act(self) -> str:
        """行动阶段：执行在思考阶段决定的具体操作。
        
        这是 ReAct 框架的第二个阶段，负责：
        1. 根据思考结果执行具体操作
        2. 与外部系统交互（如调用工具、API等）
        3. 处理执行结果并更新状态
        4. 返回操作结果的描述
        
        Returns:
            str: 执行结果的文本描述，用于记录和后续分析
            
        Note:
            子类必须实现此方法，定义具体的行动逻辑
        """

    async def step(self) -> str:
        """执行单个 ReAct 步骤：先思考，再根据思考结果决定是否行动。
        
        这是 ReAct 循环的核心方法，按顺序执行：
        1. 调用 think() 方法进行思考和决策
        2. 根据思考结果决定是否调用 act() 方法
        3. 返回步骤执行的结果描述
        
        Returns:
            str: 步骤执行结果的描述，包括思考和行动的结果
            
        Examples:
            >>> result = await agent.step()
            >>> print(result)  # "分析完成，执行了数据查询操作"
        """
        # 第一阶段：思考
        should_act = await self.think()
        
        # 第二阶段：根据思考结果决定是否行动
        if not should_act:
            return "思考完成 - 无需进一步行动"
        
        # 执行行动并返回结果
        return await self.act()
